// Copyright (c) 2020-present,  INSPUR Co, Ltd.  All rights reserved.
// This source code is licensed under Apache 2.0 License.
#pragma once
#include "db/memtable.h"
#include "memory_arena.h"
#include "table/internal_iterator.h"

namespace rocksdb {
    //liliupeng 内存存储区迭代器
  class MemoryArenaIter : public InternalIterator {
  public:

       MemoryArenaIter(const InlineUserKeyIndex<const MemTableRep::KeyComparator &> *list,
           bool pin_value, bool encode = true)
      : iter_(list), value_pinned_(pin_value), encode_(encode){}
      ~MemoryArenaIter() override = default;

      bool Valid() const override {
        return iter_.Valid();
      }

      void SeekToFirst() override {
        iter_.SeekToFirst();
      }

      void SeekToLast() override {
        iter_.SeekToLast();
      }

      //liliupeng 先在Hash中查询，查询不到则再进行ART查询
      //target为internal_key,EncodeKey组装为memtable_key
      void Seek(const Slice& target) override {
        iter_.HashSeek(EncodeKey(&tmp_, target));
      }

      //target为internal_key,EncodeKey组装为memtable_key
      void SeekForPrev(const Slice& target) override {
        iter_.HashSeekForPrev(EncodeKey(&tmp_, target));
      }

      void Next() override {
        assert(Valid());
        iter_.Next();
      }

      bool NextAndGetResult(Slice* ret_key) override {
        assert(Valid());
        Next();
        bool is_valid = Valid();
        if (is_valid) {
          *ret_key = key();
        }
        return is_valid;
      }

      void Prev() override {
        assert(Valid());
        iter_.Prev();
      }

      //返回Slice类型（internal_key）
      Slice key() const override {
        assert(Valid());
        if(encode_){
          return GetLengthPrefixedSlice(iter_.key());
        } else{
          auto node =
              static_cast<UncodedVersionNode *>(iter_.node());
          return node->GetInternalKey();
        }
      }


      VersionNode *node(){
        return iter_.node();
      }

      //返回char*类型
      const char *Key() {
        assert(Valid());
        return iter_.key();
      }

      //返回userkey
      Slice user_key() const override {
        assert(Valid());
        if(encode_){
          Slice key = GetLengthPrefixedSlice(iter_.key());
          return Slice(key.data() + key.size() - 8);
        } else{
          auto node =
              static_cast<UncodedVersionNode *>(iter_.node());
          return node->GetKey();
        }
      }

      Slice value() const override {
        assert(Valid());
        if(encode_){
          Slice key_slice = GetLengthPrefixedSlice(iter_.key());
          return GetLengthPrefixedSlice(key_slice.data() + key_slice.size());
        } else{
          auto node =
              static_cast<UncodedVersionNode *>(iter_.node());
          return node->GetValue();
        }
      }

      #ifndef NDEBUG
      void SetPinnedItersMgr(PinnedIteratorsManager* pinned_iters_mgr) override {
        pinned_iters_mgr_ = pinned_iters_mgr;
      }
      PinnedIteratorsManager* pinned_iters_mgr_ = nullptr;
      #endif

      Status status() const override { return Status::OK(); }

      bool IsKeyPinned() const override {
        // memtable data is always pinned
        return true;
      }

      bool IsValuePinned() const override {
        // memtable value is always pinned, except if we allow inplace update.
        return value_pinned_;
      }

      // No copying allowed
      MemoryArenaIter(const MemoryArenaIter&) = delete;
      void operator=(const MemoryArenaIter&) = delete;

  protected:
      std::string tmp_;

  private:
      InlineUserKeyIndex<const MemTableRep::KeyComparator &>::Iterator iter_;
      bool value_pinned_;
      bool encode_;

  };

}